﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Timers;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using YJKCodeBase.WinForm;

namespace YJKTools
{
	[Regeneration(RegenerationOption.Manual)]
	[Transaction(TransactionMode.Manual)]
	public class AutoSaveApp : IExternalApplication
	{
		public Result OnStartup(UIControlledApplication application)
		{
			this.m_UICtrlApplication = application;
			if (AutoSaveApp._hWndRevit == null)
			{
				Process currentProcess = Process.GetCurrentProcess();
				IntPtr mainWindowHandle = currentProcess.MainWindowHandle;
				AutoSaveApp._hWndRevit = new WindowHandle(mainWindowHandle);
			}
			this.m_UICtrlApplication.Idling += this.UIAppEvent_Idling_Handler;
			string fileName = AssistFunc.GetAppRootPath() + "\\Data\\AutoSaveSettingFile.xml";
			double num = 0.0;
			if (!AutoSaveSettingFileReadWriteKit.ReadMappingFile(fileName, ref this.m_AutoSave, ref num, ref this.m_FileCount))
			{
				this.m_AutoSave = false;
				num = 30.0;
				this.m_FileCount = 5;
			}
			num *= 60000.0;
			this.m_AutoSaveTimer = new Timer(num);
			this.m_AutoSaveTimer.Elapsed += this.AutoSave;
			this.m_AutoSaveTimer.AutoReset = true;
			this.SetAutoSaveMark(this.m_AutoSave);
			application.ControlledApplication.DocumentSaved += new EventHandler<DocumentSavedEventArgs>(this.app_eventsHandlerMethod);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result OnShutdown(UIControlledApplication application)
		{
			if (this.m_AutoSaveTimer != null)
			{
				this.SetAutoSaveMark(false);
				this.m_AutoSaveTimer = null;
			}
			application.ControlledApplication.DocumentSaved -= new EventHandler<DocumentSavedEventArgs>(this.app_eventsHandlerMethod);
			application.Idling -= this.UIAppEvent_Idling_Handler;
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public void SetAutoSaveMark(bool autoSave)
		{
			this.m_AutoSave = autoSave;
			if (this.m_AutoSave)
			{
				this.m_AutoSaveTimer.Enabled = true;
				return;
			}
			this.m_AutoSaveTimer.Enabled = false;
		}

		public void SetTimerInterval(double interval)
		{
			this.m_AutoSaveTimer.Interval = interval;
		}

		public void SetFileCount(int count)
		{
			this.m_FileCount = count;
		}

		[DllImport("user32.dll")]
		public static extern IntPtr GetActiveWindow();

		[DllImport("user32.dll")]
		public static extern IntPtr SetActiveWindow(IntPtr hwnd);

		private void AutoSave(object source, ElapsedEventArgs e)
		{
			if (!this.AcitveCurrentRevit())
			{
				return;
			}
			this.m_StartSaveMark = true;
		}

		public void UIAppEvent_Idling_Handler(object sender, IdlingEventArgs args)
		{
			if (!this.m_AutoSave || !this.m_StartSaveMark)
			{
				return;
			}
			UIApplication uiapplication = sender as UIApplication;
			RevitCommandId revitCommandId = RevitCommandId.LookupPostableCommandId(Autodesk.Revit.UI.PostableCommand.Save);
			try
			{
				if (uiapplication.CanPostCommand(revitCommandId))
				{
					uiapplication.PostCommand(revitCommandId);
				}
			}
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
			{
			}
		}

		private void app_eventsHandlerMethod(object obj, RevitAPIPostDocEventArgs args)
		{
			Document document = args.Document;
			if (this.m_AutoSave && this.m_StartSaveMark)
			{
				this.m_StartSaveMark = false;
				string pathName = document.PathName;
				string fileExpandedName = this.GetFileExpandedName(pathName);
				string path = this.GetPath(pathName);
				string fileName = this.GetFileName(pathName);
				string filePureName = this.GetFilePureName(fileName);
				FileInfo fileInfo = new FileInfo(pathName);
				DateTime lastWriteTime = fileInfo.LastWriteTime;
				TimeSpan t = TimeSpan.MaxValue;
				List<string> list = new List<string>();
				list = this.GetAllFile(path, fileExpandedName);
				int i = 0;
				int num = -1;
				while (i < list.Count)
				{
					string text = list[i];
					if (text.IndexOf(filePureName) != -1 && text.CompareTo(pathName) != 0)
					{
						FileInfo fileInfo2 = new FileInfo(text);
						DateTime lastWriteTime2 = fileInfo2.LastWriteTime;
						TimeSpan timeSpan = lastWriteTime - lastWriteTime2;
						if (timeSpan < t)
						{
							t = timeSpan;
							num = i;
						}
					}
					i++;
				}
				if (num != -1)
				{
					FileInfo fileInfo3 = new FileInfo(list[num]);
					DateTime lastWriteTime3 = fileInfo3.LastWriteTime;
					string text2 = string.Concat(new string[]
					{
						lastWriteTime3.Year.ToString(),
						".",
						lastWriteTime3.Month.ToString(),
						".",
						lastWriteTime3.Day.ToString(),
						".",
						lastWriteTime3.Hour.ToString(),
						".",
						lastWriteTime3.Minute.ToString(),
						".",
						lastWriteTime3.Second.ToString()
					});
					string destFileName = string.Concat(new string[]
					{
						path,
						filePureName,
						"_HY(",
						text2,
						").",
						fileExpandedName
					});
					try
					{
						File.Move(list[num], destFileName);
					}
					catch (Exception)
					{
					}
					list.Clear();
					list = this.GetAllFile(path, fileExpandedName);
					string value = path + filePureName + "_HY";
					List<KeyValuePair<string, TimeSpan>> list2 = new List<KeyValuePair<string, TimeSpan>>();
					for (i = 0; i < list.Count; i++)
					{
						string text3 = list[i];
						if (text3.IndexOf(value) != -1 && text3.CompareTo(pathName) != 0)
						{
							FileInfo fileInfo4 = new FileInfo(text3);
							DateTime lastWriteTime4 = fileInfo4.LastWriteTime;
							TimeSpan value2 = lastWriteTime - lastWriteTime4;
							KeyValuePair<string, TimeSpan> item = new KeyValuePair<string, TimeSpan>(text3, value2);
							list2.Add(item);
						}
					}
					list2.Sort(new AutoSaveApp.FileTimeComparer());
					for (i = 0; i < list2.Count; i++)
					{
						if (i + 1 > this.m_FileCount)
						{
							try
							{
								File.Delete(list2[i].Key);
							}
							catch (Exception)
							{
							}
						}
					}
				}
			}
		}

		private List<string> GetAllFile(string directory, string expandedName)
		{
			List<string> list = new List<string>();
			DirectoryInfo directoryInfo = new DirectoryInfo(directory);
			string searchPattern = "*." + expandedName;
			foreach (FileInfo fileInfo in directoryInfo.GetFiles(searchPattern))
			{
				list.Add(fileInfo.FullName);
			}
			return list;
		}

		private string GetPath(string fileFillPath)
		{
			int num = fileFillPath.LastIndexOf("\\");
			return fileFillPath.Substring(0, num + 1);
		}

		private string GetFileName(string fileFillPath)
		{
			int num = fileFillPath.LastIndexOf("\\");
			return fileFillPath.Substring(num + 1, fileFillPath.Length - num - 1);
		}

		private string GetFilePureName(string fileName)
		{
			int length = fileName.LastIndexOf(".");
			return fileName.Substring(0, length);
		}

		private string GetFileExpandedName(string fileFillPath)
		{
			int num = fileFillPath.LastIndexOf(".");
			return fileFillPath.Substring(num + 1, fileFillPath.Length - num - 1);
		}

		[DllImport("User32.dll")]
		private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

		[DllImport("User32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		private bool AcitveCurrentRevit()
		{
			try
			{
				AutoSaveApp.ShowWindowAsync(AutoSaveApp._hWndRevit.Handle, 8);
			}
			catch (Exception)
			{
				try
				{
					AutoSaveApp.SetForegroundWindow(AutoSaveApp._hWndRevit.Handle);
					return true;
				}
				catch (Exception)
				{
					return false;
				}
			}
			bool result;
			try
			{
				AutoSaveApp.SetForegroundWindow(AutoSaveApp._hWndRevit.Handle);
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private const int SW_SHOWNA = 8;

		public static WindowHandle _hWndRevit;

		private UIControlledApplication m_UICtrlApplication;

		private Timer m_AutoSaveTimer;

		private bool m_AutoSave;

		private bool m_StartSaveMark;

		private int m_FileCount = 5;

		public class FileTimeComparer : IComparer<KeyValuePair<string, TimeSpan>>
		{
			public int Compare(KeyValuePair<string, TimeSpan> lhv, KeyValuePair<string, TimeSpan> rhv)
			{
				return TimeSpan.Compare(lhv.Value, rhv.Value);
			}
		}
	}
}
